#!/usr/bin/env python

import os, sys
import subprocess
import dbus, dbus.glib, dbus.service
import gobject
import pynotify

if os.path.islink(__file__):
    this_file = os.readlink(__file__)
else:
    this_file = __file__

LOGO = os.path.join(os.path.realpath(os.path.dirname(this_file)), 'logo.png')
NOTIFY_SOUND = os.path.join(os.path.realpath(os.path.dirname(this_file)), 'phone-outgoing-busy.ogg')

def whereis(program):
    for path in os.environ.get('PATH', '').split(':'):
        if os.path.exists(os.path.join(path, program)) and \
           not os.path.isdir(os.path.join(path, program)):
            return os.path.join(path, program)
    return None

MPLAYER = whereis('mplayer')

class TXServer(dbus.service.Object):
    def __init__(self):
        name = dbus.service.BusName('org.auv.tx.Server', bus=dbus.SessionBus())
        dbus.service.Object.__init__(self, name, '/org/auv/tx/Server')

        self.reminders = []
        self.remid = 0
        self.ticks = 0
        self.timer = gobject.timeout_add(1000, self.progress_timeout)

    @dbus.service.method('org.auv.tx.Server')
    def queue(self, time, unit, message):
        time = int(time)
        due_tick = self.ticks
        if unit == 's':
            due_tick += time
        elif unit == 'm':
            due_tick += time * 60
        elif unit == 'h':
            due_tick += time * 3600
        else:
            return

        self.remid += 1
        self.reminders.append([due_tick, message, self.remid])

    @dbus.service.method('org.auv.tx.Server')
    def dump(self):
        ret = []
        for r in self.reminders:
            ret.append([r[2], r[0] - self.ticks, str(r[1])])
        return str(ret)

    @dbus.service.method('org.auv.tx.Server')
    def remove(self, remid):
        for i in self.reminders:
            if int(i[2]) == int(remid):
                self.reminders.remove(i)
                break

    def progress_timeout(self):
        self.ticks += 1
        tobedel = []
        for i in self.reminders:
            if i[0] <= self.ticks:
                self.notify(i[1])
                subprocess.Popen(['/usr/bin/mplayer', "/home/auv/HHWork/bendanci/phone-outgoing-busy.ogg"], shell=False)
                tobedel.append(i)

        for i in tobedel:
            self.reminders.remove(i)

        return True

    def notify(self, message):
        pynotify.init("TX")
        noti = pynotify.Notification(' ', ' ')
        noti.set_urgency(pynotify.URGENCY_CRITICAL)

        title = 'TX Message'
        noti.update(title, message, LOGO)
        noti.set_timeout(5000)
        noti.show()

    def run(self):
        loop = gobject.MainLoop()
        loop.run()

class TXClient:
    def __init__(self):
        bus = dbus.SessionBus()
        self.txService = bus.get_object('org.auv.tx.Server', '/org/auv/tx/Server')

    def queue(self, time, unit, message):
        queue = self.txService.get_dbus_method('queue', 'org.auv.tx.Server')
        queue(time, unit, message)

    def dump(self):
        dump = self.txService.get_dbus_method('dump', 'org.auv.tx.Server')
        reminders = eval(dump())

        print '|', 'id'.center(4), '|', 'exp'.center(7), '|', 'msg'
        if len(reminders) > 0:
            for r in reminders:
                print '|', str(r[0]).center(4), '|', str(r[1]).center(7), '|', str(r[2])
        else:
            print ' --- no reminder exist ---'

    def remove(self, remid):
        remove = self.txService.get_dbus_method('remove', 'org.auv.tx.Server')
        remove(remid)

def show_usage():
    print "Usage (Server mode): TX -d"
    print "Usage (Client mode):"
    print "    TX z time msg\tAdd alert\ttime<digital+smh>, msg<string>"
    print "    TX s remid        \tDelete alert\tremid<digital>"
    print "    TX c              \tDump alert"

if __name__ == '__main__':
    for a in sys.argv:
        if a == '-d':
            s = TXServer()
            s.run()
            sys.exit(0)

    argc = len(sys.argv)
    if argc > 1:
        if sys.argv[1] == 'z':
            if argc >= 4:
                time = sys.argv[2]
                if time[-1] in 'smh':
                    unit = time[-1]
                    time = time[:-1]
                else:
                    unit = 's'
                message = ' '.join(sys.argv[3:])

                try:
                    int(time)
                except:
                    show_usage()
                    sys.exit(0)

                try:
                    c = TXClient()
                    c.queue(time, unit, message)
                except dbus.exceptions.DBusException:
                    print "TX Server not running, try command 'TX -d' first."
                finally:
                    sys.exit(0)
        elif sys.argv[1] == 's':
            if argc >= 3:
                try:
                    int(sys.argv[2])
                except:
                    show_usage()
                    sys.exit(0)

                try:
                    c = TXClient()
                    c.remove(sys.argv[2])
                except dbus.exceptions.DBusException:
                    print "TX Server not running, try command 'TX -d' first."
                finally:
                    sys.exit(0)
        elif sys.argv[1] == 'c':
                try:
                    c = TXClient()
                    c.dump()
                except dbus.exceptions.DBusException:
                    print "TX Server not running, try command 'TX -d' first."
                finally:
                    sys.exit(0)
    show_usage()

